package com.tvunetworks.center.device.interceptor;

import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.model.dto.CheckAuthDTO;
import com.tvunetworks.center.common.util.HttpUtil;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.device.service.feign.AccessFeignService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;

/**
 * @author lebronchen
 * @create: 2019-07-04 14:36
 **/
@Slf4j
public class OpenApiInterceptor implements HandlerInterceptor {

	@Autowired
	private AccessFeignService accessFeignService;

	@Value("${accessApp.function.name}")
	private String accessAppFunctionName;

	private static HashMap<String, String> FUNCTIONNAMEMAP;
	private static final String DEFAULT_FUNCTION_NAME = "default";

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

		String requestURI = request.getRequestURI();
		if (! (StringUtils.containsIgnoreCase(requestURI, LocalConstant.OPEN_API_PATH) || StringUtils.containsIgnoreCase(requestURI, LocalConstant.UNIFORM_API_PATH))) {
			return true;
		}
		if ((StringUtils.containsIgnoreCase(requestURI, "getGridMetadata")
				|| StringUtils.containsIgnoreCase(requestURI, "updateGridMetadata")
				|| StringUtils.containsIgnoreCase(requestURI, "modifyPackName")
		)) {
			return true;
		}

		String accessToken = request.getHeader(LocalConstant.API_HEADER_PARAM_KEY);
		String contentType = request.getContentType();
		if (StringUtils.isBlank(accessToken) && "application/xml".equals(contentType)) {
			//xml请求到control认证
//			log.error("OpenApiInterceptor header not exist");
//			paramError(response, "OpenApiInterceptor header not exist");
			return true;
		}

		if (StringUtils.isBlank(accessToken)){
			log.error("accessToken is null");
			paramError(response, "accessToken is null");
			return false;
		}

		CheckAuthDTO checkAuthDTO = null;
		try {
			checkAuthDTO = JsonUtil.toObject(accessToken, CheckAuthDTO.class);
		} catch (IOException e) {
			log.error(e.toString(), e);
			log.error("OpenApiInterceptor parse json failed accessToken:[{}]", accessToken);
			paramError(response, "OpenApiInterceptor parse json failed");
			return false;
		}

		if (checkAuthDTO.paramError()) {
			log.error("OpenApiInterceptor exist field null checkAuthDTO:[{}]", checkAuthDTO);
			paramError(response, "OpenApiInterceptor exist field null");
			return false;
		}

		String ip = HttpUtil.getClientPublicIP(request);
		checkAuthDTO.setIp(ip);
		String function = getFunction(requestURI);
		checkAuthDTO.setFunction(function);
		Result<Void> checkAuthResult = accessFeignService.checkAuth(checkAuthDTO);
		if (checkAuthResult.assertSuccess()) {
			return true;
		} else {
			String result = null;
			try {
				result = JsonUtil.toJsonStr(checkAuthResult);
			} catch (IOException e) {
				log.error(e.toString(), e);
			}
			response.setStatus(HttpStatus.OK.value());
			try {
				if (result!=null){

					response.getWriter().write(result);
				}
			} catch (IOException e) {
				log.error(e.toString());
			}

			return false;
		}
	}

	private void paramError(HttpServletResponse response, String msg) {

		String result ="";
		try {
			Result errorResult = ResultUtil.checkAuthParamError();
			errorResult.setResult(msg);
			result = JsonUtil.toJsonStr(errorResult);
		} catch (IOException e) {
			log.error(e.toString(), e);
		}
		response.setStatus(HttpStatus.OK.value());
		try {
			response.getWriter().write(result);
		} catch (Exception e) {
			log.error(e.toString());
		}
	}

	private String getFunction(String requestURI) {
		if (FUNCTIONNAMEMAP == null) {
			try {
				FUNCTIONNAMEMAP = JsonUtil.toObject(accessAppFunctionName, HashMap.class);
			} catch (IOException e) {
				log.error(e.toString(), e);
			}
		}
		if (CollectionUtils.isEmpty(FUNCTIONNAMEMAP)) {
			return DEFAULT_FUNCTION_NAME;
		}
		int index = requestURI.indexOf("api");
		String key = requestURI.substring(index + 4);
		String function = FUNCTIONNAMEMAP.get(key);
		if (StringUtils.isBlank(function)) {
			return DEFAULT_FUNCTION_NAME;
		}
		return function;
	}
}